package com.tiancheng.trade.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiancheng.trade.commom.web.http.PlatformRequest;
import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.commom.core.data.Result;
import com.tiancheng.trade.commom.core.exception.BusinessException;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.order.bo.ums.BindingBankCardBO;
import com.tiancheng.trade.order.enums.*;
import com.tiancheng.trade.order.feign.UmsService;
import com.tiancheng.trade.order.mapper.BankCardMapper;
import com.tiancheng.trade.order.model.BankCard;
import com.tiancheng.trade.order.service.BankCardService;
import com.tiancheng.trade.commom.core.utils.DateTimeUtil;
import com.tiancheng.trade.order.util.ObjectConvertUtil;
import com.tiancheng.trade.order.util.SensitiveDataUtil;
import com.tiancheng.trade.order.util.helper.OrderIdHelper;
import com.tiancheng.trade.order.util.lock.Lock;
import com.tiancheng.trade.order.util.ums.UmsBindingBankCardConfig;
import com.tiancheng.trade.order.vo.admin.QueryBankCardVO;
import com.tiancheng.trade.order.vo.admin.res.QueryBankCardResVO;
import com.tiancheng.trade.order.vo.app.BankCardBindingVo;
import com.tiancheng.trade.order.vo.app.SetCardVO;
import com.tiancheng.trade.order.vo.app.UnboundCardVO;
import com.tiancheng.trade.order.vo.app.res.BankCardBindingResVo;
import com.tiancheng.trade.order.vo.app.res.BankCardVO;
import com.tiancheng.trade.order.vo.app.res.BankInfoVo;
import com.tiancheng.trade.order.vo.open.OpenUmsAccStatusQueryRes;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicHeader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.Collator;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: likailun
 * @Description: 用户绑卡service实现
 * @Date: create in 2021/8/23 3:58 下午
 */
@Slf4j
@Service
public class BankCardServiceImpl implements BankCardService {

    @Resource
    private BankCardMapper bankCardMapper;
    @Resource
    private OrderIdHelper orderIdHelper;
    @Resource
    private UmsService umsService;
    @Resource
    private UmsBindingBankCardConfig bankCardConfig;
    @Resource
    private PlatformRequest platformRequest;

    @Value(value = "${system.oneCode.domain}")
    private String oneCodeDomain;

    /**
     * 获取用户已绑定的银行列表
     *
     * @param uid 用户id
     * @return 绑卡信息
     */
    @Override
    public List<BankCardVO> queryByUid(String uid) {
        List<BankCardVO> bankCardVOS = new ArrayList<>();
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", uid);
        conditions.eq("activate_status", CardActivateStatusEnum.SUCCESS.getCode());
        conditions.orderByDesc("id");
        List<BankCard> bankCards = bankCardMapper.selectList(conditions);
        if (CollectionUtils.isNotEmpty(bankCards)) {
            for (BankCard bankCard : bankCards) {
                bankCardVOS.add(bankCard2BankCardVO(bankCard));
            }
        }
        return bankCardVOS;
    }

    /**
     * 查询绑定状态
     *
     * @param uid    用户id
     * @param flowId 绑卡申请id
     * @return 绑定信息
     */
    @Override
    public BankCardVO queryBindingStatus(String uid, String flowId) {
        BankCard bankCards = this.queryByUidAndFlowId(uid,flowId);
        BusinessErrorInfoEnum.BANK_CARD_BINDING_FLOW_NON_EXISTENT.assertIsTrue(bankCards != null && bankCards.getId() != null);
        if (bankCards.getActivateStatus().toString().equals(CardActivateStatusEnum.WAIT.getCode()) ||
                bankCards.getActivateStatus().toString().equals(CardActivateStatusEnum.SELECT_CARD.getCode())) {
            // 状态为未开通时，去银联查询一次状态
            OpenUmsAccStatusQueryRes result = umsService.queryOpenInfo(bankCards.getFlowId(), bankCards.getCreatedDt(), bankCards.getSn());
            try {
                final String status = this.updateFlowStatusByUmsMessage(result, bankCards);
                if (!status.equals(bankCards.getActivateStatus().toString())) {
                    // 状态有变化的话重新查询一次
                    QueryWrapper<BankCard> conditions = new QueryWrapper<>();
                    conditions.eq("uid", uid);
                    conditions.eq("flow_id", flowId);
                    bankCards = bankCardMapper.selectOne(conditions);
                }
            } catch (BusinessException be) {
                if (be.getErrorInfo().getCode() == BusinessErrorInfoEnum.BANK_CARD_BINDING_CALLBACK_NOT_ORDER.getCode()
                        || be.getErrorInfo().getCode() == BusinessErrorInfoEnum.BANK_CARD_BINDING_CALLBACK_REPEAT.getCode()) {
                    log.error("更新银联绑卡结果异常，error:{}", be.getErrorInfo().getMessage());
                }
            }
        }
        return this.bankCard2BankCardVO(bankCards);
    }

    @Override
    public BankCard queryByUidAndFlowId(String uid, String flowId) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", uid);
        conditions.eq("flow_id", flowId);
        return bankCardMapper.selectOne(conditions);
    }

    /**
     * 申请绑定银行卡
     *
     * @param params 绑卡参数
     * @return
     */
    @Override
    public BankCardBindingResVo binding(BankCardBindingVo params) {
        try (Lock lock = new Lock(Lock.LOCK_BANK_CARD_BINDING, params.getUid(), 5, 10)) {
            BusinessErrorInfoEnum.BANK_CARD_BINDING_TIMEOUT.assertIsTrue(lock.getLockRes());

            BankCardBindingResVo bankCardBindingResVo = new BankCardBindingResVo();
            QueryWrapper<BankCard> conditions = new QueryWrapper<>();
            conditions.eq("uid", params.getUid());
            conditions.eq("bank_code", params.getBankCode());
            conditions.eq("acc_type",params.getAccType());
            conditions.in("activate_status", new String[]{CardActivateStatusEnum.WAIT.getCode(), CardActivateStatusEnum.SELECT_CARD.getCode()});
            BankCard openedRecord = bankCardMapper.selectOne(conditions);
            // 标识是否需要新生成一笔绑卡流水
            boolean createNewOrder = (openedRecord == null || openedRecord.getId() == null);
            if (!createNewOrder) {
                // false 判断是否超过操作时效
                createNewOrder=openedRecord.getExpiryTime().isBefore(LocalDateTime.now());
                if(createNewOrder){
                    log.info("超过sn时效，关闭订单！订单：{}", JSON.toJSONString(openedRecord));
                    final BankCard updEntity = new BankCard();
                    updEntity.setActivateStatus(Integer.valueOf(CardActivateStatusEnum.INVALID.getCode()));
                    updEntity.setLastUpdDt(LocalDateTime.now());
                    this.bankCardMapper.update(updEntity,conditions);
                }
            }

            final LocalDateTime now = LocalDateTime.now();
            BindingBankCardBO bo = new BindingBankCardBO();
            bo.setBackUrl(bankCardConfig.getBackUrl());
            if (createNewOrder) {
                //商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
                bo.setOrderNo(orderIdHelper.getBindingBankCardId(params.getUid(), OperateCodeEnum.BINDING_BANK_CARD));
                bo.setOrderTime(DateTimeUtil.format(now, "yyyyMMddhhmmss"));

                final Map<String, Object> userInfo = this.getUserInfo(params.getUid());

                BankCard bankCard = ObjectConvertUtil.convert(bo, BankCard.class).get();
                bankCard.setUid(params.getUid());
                bankCard.setFlowId(bo.getOrderNo());
                bankCard.setActivateStatus(Integer.parseInt(CardActivateStatusEnum.WAIT.code()));
                bankCard.setIsDefault(0);
                bankCard.setCreatedDt(now);
                bankCard.setCertifId(MapUtils.getString(userInfo,"id_number"));
                bankCard.setCertifTp("01");
                bankCard.setMobile(MapUtils.getString(userInfo,"mobile"));
                bankCard.setBankCode(params.getBankCode());
                bankCard.setBankName(params.getBankName());
                bankCard.setBankLogoUrl(params.getBankLogoUrl());
                bankCard.setAccType(params.getAccType());
                bankCard.setCustomerName(MapUtils.getString(userInfo,"name"));

                params.setCertifId(bankCard.getCertifId());
                params.setCertifTp(bankCard.getCertifTp());
                params.setName(bankCard.getCustomerName());
                params.setMobile(bankCard.getMobile());
                final String sn = umsService.bindingCard(bo, params);
                if (StringUtils.isEmpty(sn)) {
                    // 绑卡申请失败
                    BusinessErrorInfoEnum.BANK_CARD_BINDING_ERROR.assertFail();
                }
                bankCardBindingResVo.setSn(sn);
                bankCard.setSn(sn);
                // 3小时后过期
                bankCard.setExpiryTime(LocalDateTime.now().plusHours(3));
                this.bankCardMapper.insert(bankCard);
                log.info("获取绑卡订单，new order:{}", bankCardBindingResVo);
                bankCardBindingResVo.setFlowId(bankCard.getFlowId());
                return bankCardBindingResVo;
            } else {
                bankCardBindingResVo.setFlowId(openedRecord.getFlowId());
                bankCardBindingResVo.setSn(openedRecord.getSn());
                return bankCardBindingResVo;
            }
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(BusinessErrorInfoEnum.BANK_CARD_BINDING_TIMEOUT, null, e.getMessage(), e);
        }
    }

    /**
     * 判断token是不是重复
     * @param queryRes 银联返回的绑卡结果
     */
    private boolean checkTokenRepeat(OpenUmsAccStatusQueryRes queryRes) {
        boolean repeat=false;
        if(queryRes.getStatus().equals(CardActivateStatusEnum.SUCCESS.getCode()) && StringUtils.isNotEmpty(queryRes.getToken())){
            // 返回了token，排除是重复绑定卡成功，
            QueryWrapper<BankCard> conditions=new QueryWrapper<>();
            conditions.eq("token", queryRes.getToken());
            conditions.eq("activate_status", CardActivateStatusEnum.SUCCESS.getCode());
            final List<BankCard> bankCard = this.bankCardMapper.selectList(conditions);
            if(CollectionUtils.isNotEmpty(bankCard)){
                // 已经绑定成功了卡片，设置本次回调的绑卡为失败
                conditions.clear();
                conditions.eq("flow_id", queryRes.getOrderNo());
                final BankCard updBankCard = this.getUpdateBankCard(queryRes);
                updBankCard.setActivateStatus(Integer.valueOf(CardActivateStatusEnum.REPEAT_BOUNDED.getCode()));
                this.bankCardMapper.update(updBankCard, conditions);
                repeat=true;
                log.warn("重复开卡，已存在开卡flow：{}，新申请开卡flow：{}",bankCard.get(0).getFlowId(),queryRes.getOrderNo());
            }
            conditions.clear();
        }
        return repeat;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void unbound(SetCardVO params) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", params.getUid());
        conditions.eq("flow_id", params.getFlowId());
        BankCard bankCard = this.bankCardMapper.selectOne(conditions);
        BusinessErrorInfoEnum.BANK_CARD_BINDING_FLOW_NON_EXISTENT.assertIsTrue(bankCard!=null);
        BusinessErrorInfoEnum.BANK_CARD_BINDING_STATUS_ERROR.assertIsTrue(bankCard.getActivateStatus().toString().equals(CardActivateStatusEnum.SUCCESS.getCode()));
        final boolean b = umsService.unboundCard(bankCard,orderIdHelper.getBindingBankCardId(params.getUid(),OperateCodeEnum.UNBOUNDED_BANK_CARD));
        BusinessErrorInfoEnum.BANK_CARD_UNBOUND_ERROR.assertIsTrue(b);
        final BankCard updBankCard = new BankCard();
        updBankCard.setActivateStatus(Integer.parseInt(CardActivateStatusEnum.UNBOUNDED.getCode()));
        updBankCard.setLastUpdDt(LocalDateTime.now());
        this.bankCardMapper.update(updBankCard,conditions);

        if(bankCard.getIsDefault().equals(1)){
            // 如果是默认卡，则需要重新挑选一张设置为默认卡
            conditions.clear();
            conditions.eq("uid", params.getUid());
            conditions.eq("activate_status", CardActivateStatusEnum.SUCCESS.getCode());
            conditions.orderByAsc("id");
            final List<BankCard> bankCards = this.bankCardMapper.selectList(conditions);
            if(CollectionUtils.isNotEmpty(bankCards)){
                QueryWrapper<BankCard> updateConditions = new QueryWrapper<>();
                updateConditions.eq("uid", bankCards.get(0).getUid());
                updateConditions.eq("flow_id", bankCards.get(0).getFlowId());
                final BankCard defaultBankCard = new BankCard();
                defaultBankCard.setIsDefault(1);
                defaultBankCard.setLastUpdDt(LocalDateTime.now());
                this.bankCardMapper.update(defaultBankCard,updateConditions);
            }
        }
    }

    @Override
    public void openCardCallbackHandler(Map<String, String> msgMap) {
        final OpenUmsAccStatusQueryRes entity = umsService.openCardMsgMap2Entity(msgMap);
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        //conditions.eq("acc_no", entity.getAccNo());
        if(checkTokenRepeat(entity)){
            // 重复开卡，更新新申请的开卡记录状态为：重复开卡
            return;
        }
        conditions.eq("flow_id", entity.getOrderNo());
        final BankCard bankCard = this.bankCardMapper.selectOne(conditions);
        updateFlowStatusByUmsMessage(entity, bankCard);
    }

    @Override
    public List<BankInfoVo> queryBankList() {
        final List<BankInfoVo> bankInfoVos = umsService.queryBankList(orderIdHelper.getQueryBankListId(DateTimeUtil.format(LocalDateTime.now(), "yyyyMMddhhmmss")));
        if(CollectionUtils.isNotEmpty(bankInfoVos)){
            // 根据字母顺序排列A-Z
            final Collator com = Collator.getInstance(Locale.US);
            bankInfoVos.sort((o1, o2) -> com.compare(o1.getInitials(), o2.getInitials()));

            // 常用银行处理
            List<BankInfoVo> finalList = new ArrayList<>();
            for (ToppingBankEnum item : ToppingBankEnum.values()) {
                bankInfoVos.stream().filter(bankInfoVo -> bankInfoVo.getBankCode().equals(item.getCode())).findFirst().ifPresent(bankInfoVo -> {
                    BankInfoVo vo = ObjectConvertUtil.convert(bankInfoVo, BankInfoVo.class).get();
                    vo.setInitials("常用");
                    finalList.add(vo);
                });
            }
            finalList.addAll(bankInfoVos);
            return finalList;
        }
        return bankInfoVos;
    }

    @Transactional
    @Override
    public void setDefaultPayCard(SetCardVO params) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", params.getUid());
        conditions.eq("activate_status",CardActivateStatusEnum.SUCCESS.getCode());
        final List<BankCard> bankCards = this.bankCardMapper.selectList(conditions);
        BusinessErrorInfoEnum.BANK_CARD_BINDING_CARD_NON_EXISTENT.assertIsTrue(CollectionUtils.isNotEmpty(bankCards));
        final List<BankCard> collect = bankCards.stream().filter(bankCard -> bankCard.getFlowId().equals(params.getFlowId())).collect(Collectors.toList());
        BusinessErrorInfoEnum.BANK_CARD_BINDING_CARD_NON_EXISTENT.assertIsTrue(CollectionUtils.isNotEmpty(collect));

        if(collect.get(0).getIsDefault().equals(1)){
            return;
        }
        //设置该卡片为：默认支付卡
        final BankCard defaultCard = new BankCard();
        defaultCard.setIsDefault(1);
        conditions.eq("id", collect.get(0).getId());
        conditions.eq("flow_id", params.getFlowId());
        this.bankCardMapper.update(defaultCard, conditions);

        if (CollectionUtils.isNotEmpty(collect) && bankCards.size() > 1) {
            // 设置用户其他卡片为：非默认支付卡
            final BankCard notDefaultCard = new BankCard();
            notDefaultCard.setIsDefault(0);
            QueryWrapper<BankCard> notDefaultConditions = new QueryWrapper<>();
            notDefaultConditions.eq("uid", params.getUid());
            notDefaultConditions.in("flow_id", bankCards.stream().map(BankCard::getFlowId).filter(flowId -> !flowId.equals(params.getFlowId())).collect(Collectors.toList()));
            this.bankCardMapper.update(notDefaultCard, notDefaultConditions);
        }
    }

    @Override
    public void unboundAllBankCard(UnboundCardVO params) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", params.getUid());
        conditions.eq("activate_status",CardActivateStatusEnum.SUCCESS.getCode());
        List<BankCard> bankCards = this.bankCardMapper.selectList(conditions);
        if(CollectionUtils.isEmpty(bankCards)){
            return;
        }
        List<String> success=new ArrayList<>();
        List<String> fail=new ArrayList<>();
        for (BankCard bankCard : bankCards) {
            final boolean b = umsService.unboundCard(bankCard,orderIdHelper.getBindingBankCardId(params.getUid(),OperateCodeEnum.UNBOUNDED_BANK_CARD));
            if(b){
                success.add(bankCard.getFlowId());
                continue;
            }
            fail.add(bankCard.getFlowId());
        }

        if(CollectionUtils.isNotEmpty(success)){
            final BankCard updBankCard = new BankCard();
            updBankCard.setActivateStatus(Integer.parseInt(CardActivateStatusEnum.UNBOUNDED.getCode()));
            updBankCard.setLastUpdDt(LocalDateTime.now());
            this.bankCardMapper.update(updBankCard,conditions);
        }
        BusinessErrorInfoEnum.BANK_CARD_UNBOUND_ON_CODE_ERROR.assertIsTrue(CollectionUtils.isEmpty(fail));
        log.info("解绑用户所有银行卡成功,uid:{}",params.getUid());

    }

    @Override
    public void unboundAllBankCardAndOneCode(UnboundCardVO params) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", params.getUid());
        conditions.eq("activate_status",CardActivateStatusEnum.SUCCESS.getCode());
        List<BankCard> bankCards = this.bankCardMapper.selectList(conditions);
        if(CollectionUtils.isEmpty(bankCards)){
            BusinessErrorInfoEnum.BANK_CARD_UNBOUND_ON_CODE_ERROR.assertIsTrue(this.unboundOnCode(params.getUid()));
            log.info("未绑定银行卡，解绑一码通成功,uid:{}",params.getUid());
        }else{
            List<String> success=new ArrayList<>();
            List<String> fail=new ArrayList<>();
            for (BankCard bankCard : bankCards) {
                final boolean b = umsService.unboundCard(bankCard,orderIdHelper.getBindingBankCardId(params.getUid(),OperateCodeEnum.UNBOUNDED_BANK_CARD));
                if(b){
                    success.add(bankCard.getFlowId());
                    continue;
                }
                fail.add(bankCard.getFlowId());
            }

            if(CollectionUtils.isNotEmpty(success)){
                final BankCard updBankCard = new BankCard();
                updBankCard.setActivateStatus(Integer.parseInt(CardActivateStatusEnum.UNBOUNDED.getCode()));
                updBankCard.setLastUpdDt(LocalDateTime.now());
                this.bankCardMapper.update(updBankCard,conditions);
            }
            BusinessErrorInfoEnum.BANK_CARD_UNBOUND_ON_CODE_ERROR.assertIsTrue(CollectionUtils.isEmpty(fail));
            BusinessErrorInfoEnum.BANK_CARD_UNBOUND_ON_CODE_ERROR.assertIsTrue(this.unboundOnCode(params.getUid()));
            log.info("解绑用户所有银行卡、一码通成功,uid:{}，解绑卡数量:{}",params.getUid(),success.size());
        }
    }

    @Override
    public BankCard getDefaultCard(String uid) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", uid);
        conditions.eq("activate_status",CardActivateStatusEnum.SUCCESS.getCode());
        conditions.eq("is_default",1);
        final List<BankCard> bankCards = this.bankCardMapper.selectList(conditions);
        return CollectionUtils.isNotEmpty(bankCards)?bankCards.get(0):null;
    }

    @Override
    public PageInfo<QueryBankCardResVO> queryBankPage(QueryBankCardVO params) {
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        if(params.getId()!=null){
            conditions.eq("id",params.getId());
        }
        if(StringUtils.isNotEmpty(params.getFlowId())){
            conditions.eq("flow_id",params.getFlowId());
        }
        if(StringUtils.isNotEmpty(params.getMobile())){
            conditions.eq("mobile",params.getMobile());
        }
        if(StringUtils.isNotEmpty(params.getBankCode())){
            conditions.eq("bank_code",params.getBankCode());
        }
        if(StringUtils.isNotEmpty(params.getAccType())){
            conditions.eq("acc_type",params.getAccType());
        }
        if(StringUtils.isNotEmpty(params.getAccNo())){
            conditions.eq("acc_no",params.getAccNo());
        }
        if(null!=params.getActivateStatus()){
            conditions.eq("activate_status",params.getActivateStatus());
        }
        if(StringUtils.isNotEmpty(params.getToken())){
            conditions.eq("token",params.getToken());
        }
        if (StringUtils.isNotEmpty(params.getCreatedDtBegin()) && StringUtils.isNotEmpty(params.getCreatedDtEnd())) {
            conditions.between("created_dt",
                    DateTimeUtil.format(params.getCreatedDtBegin() + " 00:00:00", "yyyy-MM-dd HH:mm:ss"),
                    DateTimeUtil.format(params.getCreatedDtEnd() + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
        }
        conditions.orderByDesc("id");
        PageInfo<BankCard> pageInfo = bankCardMapper.find(conditions, params.getCurrentPage(), params.getPageSize());
        PageInfo<QueryBankCardResVO> pageRes = new PageInfo<>();
        List<QueryBankCardResVO> vos = pageInfo.getList().stream().map(order ->{
            final QueryBankCardResVO queryBankCardResVO = ObjectConvertUtil.convert(order, QueryBankCardResVO.class).get();
            queryBankCardResVO.setCustomerName(SensitiveDataUtil.userNameEncrypt(queryBankCardResVO.getCustomerName()));
            queryBankCardResVO.setActivateStatusName(CardActivateStatusEnum.getDesc(queryBankCardResVO.getActivateStatus().toString()));
            return queryBankCardResVO;
        }).collect(Collectors.toList());

        pageRes.setList(vos);
        pageRes.setPagination(pageInfo.getPagination());
        return pageRes;
    }


    /**
     * 调用一码通接口，解绑一码通
     * @param uid 用户id
     * @return 解绑结果，true-成功
     */
    private boolean unboundOnCode(String uid){
        String token = platformRequest.getAccessToken();
        Result result = platformRequest.getRequest(oneCodeDomain + "/uc/card/close-by-uid?uid="+uid,
                null, true, new BasicHeader("token", token));
        log.info("解绑一码通返回：{}",result);
        return result.getRet().equals(0);
    }

    /**
     * 调用一码通接口，解绑一码通
     * @param uid 请求数据
     * @return 解绑结果，true-成功
     */
    private Map<String, Object> getUserInfo(String uid){
        log.info("查询用户信息身份信息 uid：{}",uid);
        Result result = platformRequest.getRequest(oneCodeDomain + "/uc/card/get-one-card-info-by-uid?uid="+uid,
                null, true,new BasicHeader("token", platformRequest.getAccessToken()));
        BusinessErrorInfoEnum.BANK_CARD_QUERY_USER_INFO_ERROR.assertIsTrue(result.getRet().equals(0));
        Map<String, Object> resultMap = JsonUtil.fromJson(result.toString(), Map.class);
        Map<String, Object> dataMap = (Map<String, Object>) resultMap.get("data");
        log.info("查询用户信息返回：{}",result);
        if(MapUtils.getBoolean(dataMap,"is_register")){
            Map<String, Object> userInfo = (Map<String, Object>) dataMap.get("info");
            if(!userInfo.containsKey("mobile") || StringUtils.isEmpty(MapUtils.getString(userInfo,"mobile"))){
                userInfo.put("mobile",MapUtils.getString(dataMap,"mobile"));
            }
            BusinessErrorInfoEnum.BANK_CARD_QUERY_USER_INFO_ERROR.assertIsTrue(userInfo!=null && userInfo.size()>0);
            return userInfo;
        }
        BusinessErrorInfoEnum.BANK_CARD_QUERY_USER_CODE_ERROR.assertFail();
        return null;
    }


    /**
     * 更新开卡认证结果
     *
     * @param entity   银联返回的开卡结果
     * @param bankCard 要更新记录条件
     * @return true——进行了更新，false——未更新
     */
    private String updateFlowStatusByUmsMessage(OpenUmsAccStatusQueryRes entity, BankCard bankCard) {
        if (entity.getStatus().equals(CardActivateStatusEnum.WAIT.getCode())) {
            //status==0 处理中(初始值)
            return entity.getStatus();
        }
        BusinessErrorInfoEnum.BANK_CARD_BINDING_CALLBACK_NOT_ORDER.assertIsTrue(bankCard != null && bankCard.getId() != null);
        BusinessErrorInfoEnum.BANK_CARD_BINDING_CALLBACK_REPEAT.assertIsTrue(!bankCard.getActivateStatus().toString()
                .equals(CardActivateStatusEnum.SUCCESS.getCode()));

        final BankCard updBankCard = getUpdateBankCard(entity);
        QueryWrapper<BankCard> conditions = new QueryWrapper<>();
        conditions.eq("uid", bankCard.getUid());
        if(updBankCard.getActivateStatus().toString().equals(CardActivateStatusEnum.SUCCESS.getCode())){
            QueryWrapper<BankCard> conditions1 = new QueryWrapper<>();
            conditions1.eq("uid", bankCard.getUid());
            conditions1.eq("activate_status",CardActivateStatusEnum.SUCCESS.getCode());
            conditions1.eq("is_default",1);
            final List<BankCard> bankCards = this.bankCardMapper.selectList(conditions1);
            if(CollectionUtils.isEmpty(bankCards)){
                // 没有设置默认卡
                updBankCard.setIsDefault(1);
            }
        }
        conditions.eq("flow_id", bankCard.getFlowId());
        this.bankCardMapper.update(updBankCard, conditions);
        return updBankCard.getActivateStatus().toString();
    }

    /**
     * 构建更新实体
     * @param entity
     * @return
     */
    private BankCard getUpdateBankCard(OpenUmsAccStatusQueryRes entity) {
        final BankCard updBankCard = new BankCard();

        updBankCard.setLastUpdDt(LocalDateTime.now());// 更新时间
        updBankCard.setActivateStatus(Integer.parseInt(entity.getStatus()));//设置开卡状态
        if (StringUtils.isNotEmpty(entity.getAccNo())) {
            // 银行卡后四位
            updBankCard.setAccNo(entity.getAccNo());
        }
        if (entity.getStatus().equals(CardActivateStatusEnum.SUCCESS.getCode())) {
            /**
             * status==2 绑卡成功
             *  绑卡成功，此时会有bindCardInfo
             *  origReqType（原交易类型0470001903：绑卡请求；0510001903：云闪付APP主动发起的解绑请求）
             */
            updBankCard.setBindingTime(LocalDateTime.now());//绑定成功时间
            updBankCard.setActivateStatus(Integer.parseInt(entity.getStatus()));
            if (StringUtils.isNotEmpty(entity.getMobile())) {
                updBankCard.setMobile(entity.getMobile());
            }
            if (StringUtils.isNotEmpty(entity.getToken())) {
                updBankCard.setToken(entity.getToken());
            }
            if (StringUtils.isNotEmpty(entity.getCloudPayUserId())) {
                updBankCard.setUnionpayUserId(entity.getCloudPayUserId());
            }

        }
        if (StringUtils.isNotEmpty(entity.getOrigReqType()) && UmsTradeTypeEnum.unionpay_unbounded_req.getCode().equals(entity.getOrigReqType())) {
            // 云闪付APP主动发起的解绑请求,状态设置未5-解绑
            updBankCard.setActivateStatus(Integer.parseInt(CardActivateStatusEnum.UNBOUNDED.code()));
        } else {
            //status in(1、3、4) 1-用户已选卡，3、绑卡失败，4、sn失效
            updBankCard.setActivateStatus(Integer.parseInt(entity.getStatus()));
        }
        return updBankCard;
    }


    private BankCardVO bankCard2BankCardVO(BankCard bankCard) {
        BankCardVO bankCardVO = ObjectConvertUtil.convert(bankCard, BankCardVO.class).get();
        bankCardVO.setBackgroundImg(umsService.getBackgroundImg(bankCard.getBankCode()));
        // TODO 填充银行名称、银行logo信息，银行卡脱敏
        return bankCardVO;
    }

}
